"""
Case Type   : ustore_DQL_SET_OPERATIONS
Case Name   : intersect/intersect all/except/except all结合order by/limit
Create At   : 2022-05-12
Owner       : nanyang12
Description :
    1.创建表
    2.使用copy命令插入数据
    3.创建索引
    4.intersect/intersect all/except/except all结合order by/limit
    5.环境清理
Expect      :
    1.创建成功
    2.数据插入成功
    3.创建成功
    4.成功
    5.清理成功
History     :
"""

import os
import subprocess
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Ustore01(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----- {os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.pri_root = Node('PrimaryRoot')
        self.com = Common()
        self.constant = Constant()
        self.table_name1 = 't_ustore_b5000_add_01'
        self.table_name2 = 't_ustore_b5000_add_02'
        self.index_name = 'idx_btree_t_ustore_b5000_add_01'
        self.copy_file1 = 'TABLE_SETOP_B5000_000_33.txt'
        self.copy_file2 = 'TABLE_SETOP_B5000_001_33.txt'
        self.cur_path_1 = os.path.join(macro.SCRIPTS_PATH, self.copy_file1)
        self.cur_path_2 = os.path.join(macro.SCRIPTS_PATH, self.copy_file2)
        self.parent_path = os.path.dirname(macro.DB_INSTANCE_PATH)
        self.target_path1 = os.path.join(self.parent_path, self.copy_file1)
        self.target_path2 = os.path.join(self.parent_path, self.copy_file2)

    def test_join(self):
        step_txt = '-----step1:创建表;expect: 创建成功-----'
        self.log.info(step_txt)
        cmd_sql = f"""drop table if exists {self.table_name1} cascade;
                         drop table if exists {self.table_name2} cascade;
                         create table {self.table_name1}(
                         C_CHAR_1 CHAR(1),
                         C_CHAR_2 CHAR(10),
                         C_CHAR_3 CHAR(100),
                         C_VARCHAR_1 VARCHAR(1),
                         C_VARCHAR_2 VARCHAR(10),
                         C_VARCHAR_3 VARCHAR(1024),
                         C_INT BIGINT,
                         C_BIGINT BIGINT,
                         C_SMALLINT BIGINT,
                         C_FLOAT FLOAT,
                         C_NUMERIC NUMERIC(20,5),
                         C_DP double precision,
                         C_DATE DATE,
                         C_TS_WITHOUT VARCHAR(100),
                         C_TS_WITH VARCHAR(100)) WITH (STORAGE_TYPE=USTORE);
                         create table  {self.table_name2}(
                         C_CHAR_1 CHAR(1),
                         C_CHAR_2 CHAR(10),
                         C_CHAR_3 CHAR(100),
                         C_VARCHAR_1 VARCHAR(1),
                         C_VARCHAR_2 VARCHAR(10),
                         C_VARCHAR_3 VARCHAR(1024),
                         C_INT BIGINT,
                         C_BIGINT BIGINT,
                         C_SMALLINT BIGINT,
                         C_FLOAT FLOAT,
                         C_NUMERIC NUMERIC(20,5),
                         C_DP double precision,
                         C_DATE DATE,
                         C_TS_WITHOUT VARCHAR(100),
                         C_TS_WITH VARCHAR(100)) WITH (STORAGE_TYPE=USTORE);"""
        self.log.info(cmd_sql)
        create_result = self.pri_sh.execut_db_sql(cmd_sql)
        self.log.info(create_result)
        self.assertTrue(
            create_result.count(self.constant.TABLE_CREATE_SUCCESS) == 2,
            '执行失败:' + step_txt)

        step_txt = '-----step2:使用copy命令插入数据，expect: 数据插入成功-----'
        self.log.info(step_txt)
        text = '-----step2.1: 获取当前主机的IP地址;expect: 成功-----'
        self.log.info(text)
        cmd = "ifconfig -a|grep inet6 -a2|grep broadcast|awk '{print $2}'"
        self.log.info(cmd)
        self.cur_ip = subprocess.getoutput(cmd).strip()
        self.log.info(self.cur_ip)

        text = '-----step2.2: 复制文件到数据库主机对应目录 expect: 成功-----'
        self.log.info(text)
        if self.cur_ip == self.pri_sh.node.ssh_host:
            self.log.info('当前主机是数据库主机，无需远程复制')
            cmd = f"cp {self.cur_path_1} {self.parent_path};" \
                f"cp {self.cur_path_2} {self.parent_path};"
            self.log.info(cmd)
            res = self.pri_sh.node.sh(cmd).result()
            self.log.info(res)
        else:
            print(self.parent_path)
            self.com.scp_file(self.pri_root, self.copy_file1,
                              self.parent_path)
            self.com.scp_file(self.pri_root, self.copy_file2,
                              self.parent_path)
            chmod_cmd = f"chmod 777 -R {self.parent_path};" \
                        f"ls -al {self.parent_path}"
            self.log.info(chmod_cmd)
            chmod_result = self.pri_root.sh(chmod_cmd).result()
            self.log.info(chmod_result)

        text = '-----step2.3: 查看数据库主机目标路径下文件 expect: 成功-----'
        self.log.info(text)
        cmd = f"ls -l {self.parent_path}| grep -E '{self.copy_file1}';" \
            f"ls -l {self.parent_path}| grep -E '{self.copy_file2}'"
        self.log.info(cmd)
        res = self.pri_root.sh(cmd).result()
        self.log.info(res)
        self.assertNotIn('No such file or directory', res, '文件拷贝失败')
        self.assertIn(f'{self.copy_file1}', res, '文件拷贝失败')
        self.assertIn(f'{self.copy_file2}', res, '文件拷贝失败')

        text = '-----step2.4:使用copy命令插入数据，expect: 数据插入成功-----'
        self.log.info(text)
        self.log.info('---------------使用copy命令插入数据------------------')
        copy_sql = f"copy {self.table_name1} from '{self.target_path1}' " \
            f"delimiters ',';" \
            f"copy {self.table_name2} from '{self.target_path2}' " \
            f"delimiters ',';"
        self.log.info(copy_sql)
        copy_result = self.pri_sh.execut_db_sql(copy_sql)
        self.log.info(copy_result)
        self.assertTrue(copy_result.count('COPY 300') == 2,
                        '执行失败:' + step_txt)

        step_txt = '-----step3: 创建索引expect: 成功-----'
        self.log.info(step_txt)
        cmd_sql = f"""
        drop index if exists {self.index_name}_01;
        drop index if exists {self.index_name}_02;
        drop index if exists {self.index_name}_03;
        drop index if exists {self.index_name}_04;
        drop index if exists {self.index_name}_05;
        drop index if exists {self.index_name}_06;
        create index {self.index_name}_01 on {self.table_name1}(C_INT);
        create index {self.index_name}_02 on {self.table_name1}(C_BIGINT);
        create index {self.index_name}_03 on {self.table_name1}(C_SMALLINT);
        create index {self.index_name}_04 on {self.table_name2}(C_INT);
        create index {self.index_name}_05 on {self.table_name2}(C_BIGINT);
        create index {self.index_name}_06 on {self.table_name2}(C_SMALLINT);"""
        self.log.info(cmd_sql)
        create_index = self.pri_sh.execut_db_sql(cmd_sql)
        self.log.info(create_index)
        self.assertTrue(create_index.count
                        (self.constant.CREATE_INDEX_SUCCESS_MSG) == 6,
                        "执行失败：" + step_txt)

        step_txt = '-----step4: intersect/intersect all/except/except all' \
                   '结合order by/limit expect: 成功-----'
        self.log.info(step_txt)
        cmd_sql = f"""
        (select C_INT from {self.table_name1} where C_INT>= 10 and C_BIGINT>30  
        group by C_INT order by C_INT limit 9515 offset 5)  
        intersect  (select C_INT from {self.table_name1} where C_INT>= 10 
        and C_BIGINT>30  group by C_INT order by C_INT limit 10000 
        offset 11) order by C_INT limit 20;
        (select C_INT from {self.table_name1} where C_INT>= 10 and C_BIGINT>30
        order by C_INT limit 90000 offset 5)  
        intersect all  (select C_INT from {self.table_name1} where C_INT>= 10 
        and C_BIGINT>30 order by C_INT limit 9500 
        offset 11) order by C_INT     limit 20;
        (select C_INT from {self.table_name1} where C_INT>= 10 and C_BIGINT>30  
        group by C_INT order by C_INT limit 9684 offset 5)  
        except  (select C_INT from {self.table_name1} where C_INT>= 10 
        and C_BIGINT>30  group by C_INT order by C_INT limit 7852 
        offset 11) order by C_INT     limit 20;"""
        self.log.info(cmd_sql)
        query_result = self.pri_sh.execut_db_sql(cmd_sql)
        self.log.info(query_result)
        self.assertTrue(query_result.count('20 rows') == 2,
                        '执行失败:' + step_txt)
        self.assertTrue(query_result.count('6 rows') == 1,
                        '执行失败:' + step_txt)


    def tearDown(self):
        step_txt = '-----step5: 环境清理 expect:清理成功-----'
        self.log.info(step_txt)
        self.log.info('由于后续用例依赖表，故先不删除')
        text = '-----删除文件-----'
        self.log.info(text)
        rm_cmd = f"rm -rf {self.target_path1};" \
            f"rm -rf {self.target_path2}"
        self.log.info(rm_cmd)
        self.com.get_sh_result(self.pri_root, rm_cmd)
        for s in [self.target_path1, self.target_path2]:
            cmd = f'if [ -f {s} ]; then echo "does exists"; ' \
                f'else echo "not exists"; fi'
            file_judgments = self.com.get_sh_result(self.pri_root, cmd)
            self.assertIn('not exists', file_judgments, "清理失败" + text)
        self.log.info(f'----- {os.path.basename(__file__)} end-----')

